using System;
using System.Threading;

namespace Kugar.Core.Communications.Transfer
{
    internal interface ITransferFactory
    {
        void Listen(TransferConnectConfig config);
        void StopListen(TransferConnectConfig port);
        void ClosePort(TransferConnectConfig port);
        //ITransfer ConnectTo(TransferConnectConfig config);
        //ITransfer ConnectTo(TransferConnectConfig config,ref Exception error);
        //IAsyncResult BeginConnectTo(TransferConnectConfig config, AsyncCallback callback, object state);
        //ITransfer EndConnectTo(IAsyncResult iar);
        //ITransfer EndConnectTo(IAsyncResult iar,ref Exception error);

        bool ConnectToAsync(TransferAsyncEventArgs ea, TransferConnectConfig config);

        void Close();
        event EventHandler<RemoteRequestConnectEventArgs> ConnectRequest;
        event EventHandler<RemoteConenctSuccessEventArgs> ConnectSuccessed;
    }

    public abstract class TransferFactoryBase : ITransferFactory
    {
        protected bool _isClosed = false;

        public abstract void Listen(TransferConnectConfig config);
        public abstract void StopListen(TransferConnectConfig port);
        public abstract void ClosePort(TransferConnectConfig port);

        public abstract bool ConnectToAsync(TransferAsyncEventArgs ea, TransferConnectConfig config);

        //public virtual ITransfer ConnectTo(TransferConnectConfig config)
        //{
        //    ITransfer transfer = null;
        //    Exception err = null;

        //    transfer = ConnectTo(config, ref err);

        //    if (err!=null)
        //    {
        //        throw err;
        //    }
        //    else
        //    {
        //        return transfer;
        //    }
        //}

        //public virtual ITransfer ConnectTo(TransferConnectConfig config, ref Exception error)
        //{
        //    var au = new AutoResetEvent(false);

        //    ITransfer transfer = null;
        //    Exception err = null;

        //    var iar = BeginConnectTo(config, (ia) =>
        //                                         {
        //                                             transfer = EndConnectTo(ia, ref err);
        //                                             au.Set();
        //                                         }, null);

        //    au.WaitOne(30000, false);

        //    error = err;

        //    return transfer;

        //}

        //public abstract IAsyncResult BeginConnectTo(TransferConnectConfig config, AsyncCallback callback, object state);

        //public virtual ITransfer EndConnectTo(IAsyncResult iar)
        //{
        //    ITransfer transfer = null;
        //    Exception err = null;

        //    transfer = EndConnectTo(iar, ref err);

        //    if (err!=null)
        //    {
        //        throw err;
        //    }
        //    else
        //    {
        //        return transfer;
        //    }

        //}

        //public abstract ITransfer EndConnectTo(IAsyncResult iar, ref Exception error);

        public abstract void Close();
        public event EventHandler<RemoteRequestConnectEventArgs> ConnectRequest;
        public event EventHandler<RemoteConenctSuccessEventArgs> ConnectSuccessed;


        protected virtual bool OnConnectRequest(RemoteRequestConnectEventArgs e)
        {
            if (ConnectRequest!=null)
            {
                e.IsEnableConnect = false;

                ConnectRequest(this, e);

                return e.IsEnableConnect;
            }
            else
            {
                return true;
            }
        }

        protected virtual void OnConnectSuccessed(RemoteConenctSuccessEventArgs e)
        {
            Events.EventHelper.RaiseAsync(ConnectSuccessed,this,e);
        }
    }
}